package com.zxl.openapi.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.zxl.openapi.constans.SystemParameter;
import com.zxl.openapi.feign.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

import java.util.Map;

import static com.zxl.openapi.constans.SystemParameter.REDIS_APILIMIEPRE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

@Component
public class LimitFilter extends ZuulFilter {

    @Autowired
    private RedisService redisService;

    @Override
    public String filterType() {

        return PRE_TYPE;

    }

    @Override
    public int filterOrder() {

        return 80;

    }

//    @Override
//    public boolean shouldFilter() {
//
//        RequestContext currentContext = RequestContext.getCurrentContext();
//
//        HttpServletRequest request = currentContext.getRequest();
//
//        String method = request.getParameter("method");
//
//        Map<Object, Object> map = redisService.hgetAll(SystemParameter.REDIS_APIPRE + method);
//
//        currentContext.put("appInfoMap",map);
//
//        return RequestContext.getCurrentContext().sendZuulResponse() && "1".equalsIgnoreCase(map.get("limit").toString());
//
//    }

    @Override
    public boolean shouldFilter() {
        //改进,因为我们分析得到api的信息没有非常多,是没有必要每个请求都去查询redis的,会浪费资源,所以我们提前把所有的api信息都加载到zuul中,已经随着程序启动放入到一个map中,此处直接获取即可
        RequestContext currentContext = RequestContext.getCurrentContext();

        HttpServletRequest request = currentContext.getRequest();
        //这个就是用户传递的要请求的地址
        String method = request.getParameter("method");

        Map<Object, Object> map = SystemParameter.allApiInfoMap.get(SystemParameter.REDIS_APIPRE + method);
        //此处又保存一次的原因是为了 后面路由的时候免得再获取一次请求参数,再去map中查
        currentContext.put("apiInfoMap", map);
         String filters = (String) map.get("filters");//获取当前过滤器需要经过的filters
        //return RequestContext.getCurrentContext().sendZuulResponse()&&"1".equalsIgnoreCase(map.get("limit").toString())&& filters != null && filters.contains(getClass().getName());
        // 这个 filter没有采用动态的原因是因为我们的接口信息中的limit就可以控制这个过滤器的生效与否
        return RequestContext.getCurrentContext().sendZuulResponse() && "1".equalsIgnoreCase(map.get("limit").toString()) && filters != null && filters.contains(getClass().getName());

    }

    @Override
    public Object run() throws ZuulException {

        RequestContext currentContext = RequestContext.getCurrentContext();

        HttpServletRequest request = currentContext.getRequest();

        String appkey = request.getParameter("appkey");

        String method = request.getParameter("method");

        System.out.println("LimitFilter中的method:" + method);

        long result = redisService.hdecr(REDIS_APILIMIEPRE + appkey, method,-1);

        if(result < 0){

            currentContext.setSendZuulResponse(false);

            currentContext.getResponse().setContentType("text/html;charset=utf-8");

            currentContext.setResponseBody("接口请求此处已经达到上限,请及时充值");

        }
        //执行次数的校验
        //先看看当前用户还剩下多少次,必须得在一个地方保存着次数,考虑到我们会有很多个接口,每个接口每个用户的次数都不一样
        //我们使用hash  key是和用户相关的,filed是个接口相关的,值和次数相关的
        //代表已经到达次数限制了,注意不能判断=0 因为=0代表之前是1
        return null;
    }
}
